import { useState, useCallback, useMemo } from 'react'

export interface UsePaginationOptions {
  /** 初始页码 */
  initialPage?: number
  /** 每页数量 */
  pageSize?: number
  /** 总数据量 */
  total?: number
}

/**
 * usePagination Hook
 * 分页管理
 */
export const usePagination = <T = any>({
  initialPage = 1,
  pageSize = 10,
  total = 0,
}: UsePaginationOptions = {}) => {
  const [currentPage, setCurrentPage] = useState(initialPage)
  const [currentPageSize, setCurrentPageSize] = useState(pageSize)
  const [totalCount, setTotalCount] = useState(total)

  // 总页数
  const totalPages = useMemo(() => {
    return Math.ceil(totalCount / currentPageSize)
  }, [totalCount, currentPageSize])

  // 是否有上一页
  const hasPrev = useMemo(() => {
    return currentPage > 1
  }, [currentPage])

  // 是否有下一页
  const hasNext = useMemo(() => {
    return currentPage < totalPages
  }, [currentPage, totalPages])

  // 开始索引
  const startIndex = useMemo(() => {
    return (currentPage - 1) * currentPageSize
  }, [currentPage, currentPageSize])

  // 结束索引
  const endIndex = useMemo(() => {
    return Math.min(startIndex + currentPageSize, totalCount)
  }, [startIndex, currentPageSize, totalCount])

  /**
   * 跳转到指定页
   */
  const goToPage = useCallback(
    (page: number) => {
      if (page >= 1 && page <= totalPages) {
        setCurrentPage(page)
      }
    },
    [totalPages]
  )

  /**
   * 上一页
   */
  const prev = useCallback(() => {
    if (hasPrev) {
      setCurrentPage((prevPage) => prevPage - 1)
    }
  }, [hasPrev])

  /**
   * 下一页
   */
  const next = useCallback(() => {
    if (hasNext) {
      setCurrentPage((prevPage) => prevPage + 1)
    }
  }, [hasNext])

  /**
   * 第一页
   */
  const first = useCallback(() => {
    setCurrentPage(1)
  }, [])

  /**
   * 最后一页
   */
  const last = useCallback(() => {
    setCurrentPage(totalPages)
  }, [totalPages])

  /**
   * 设置每页数量
   */
  const changePageSize = useCallback((size: number) => {
    setCurrentPageSize(size)
    setCurrentPage(1) // 重置到第一页
  }, [])

  /**
   * 设置总数
   */
  const setTotal = useCallback((newTotal: number) => {
    setTotalCount(newTotal)
  }, [])

  /**
   * 重置分页
   */
  const reset = useCallback(() => {
    setCurrentPage(initialPage)
    setCurrentPageSize(pageSize)
    setTotalCount(total)
  }, [initialPage, pageSize, total])

  /**
   * 获取当前页数据
   */
  const getCurrentPageData = useCallback(
    (data: T[]): T[] => {
      return data.slice(startIndex, endIndex)
    },
    [startIndex, endIndex]
  )

  /**
   * 获取分页信息文本
   */
  const getPaginationText = useCallback((): string => {
    if (totalCount === 0) {
      return '暂无数据'
    }
    return `第 ${startIndex + 1}-${endIndex} 条，共 ${totalCount} 条`
  }, [startIndex, endIndex, totalCount])

  return {
    // 状态
    currentPage,
    pageSize: currentPageSize,
    total: totalCount,
    totalPages,
    hasPrev,
    hasNext,
    startIndex,
    endIndex,

    // 方法
    goToPage,
    prev,
    next,
    first,
    last,
    changePageSize,
    setTotal,
    reset,
    getCurrentPageData,
    getPaginationText,
  }
}

export default usePagination

